using System;
using System.Data;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using Toenda.Tools.Data;
using Toenda.Tools.DataContainer;

namespace ZapprService {
	/// <summary>
	/// ErrorType as enum
	/// </summary>
	public enum ErrorType {
		/// <summary> No error </summary>
		NoError = 0,
		/// <summary> Default error </summary>
		DefaultError = 1,
		/// <summary> Incorrect username </summary>
		IncorrectUsername = 2,
		/// <summary> Incorrect password </summary>
		IncorrectPassword = 3,
		/// <summary> Default login error </summary>
		DefaultLoginError = 4,
		/// <summary> Session does not exist </summary>
		SessionNotExists = 5,
		/// <summary> No Password </summary>
		EmptyPassword = 6,
		/// <summary> Username less then 3 chars </summary>
		UsernameToSmall = 7,
		/// <summary> Emailadress is not correct </summary>
		EMailIsIncorrect = 8,
		/// <summary> The password dont agree with the check password </summary>
		PasswordsDontAgree = 9,
		/// <summary> Username exist </summary>
		UsernameExist = 10,
		/// <summary> Username disabled </summary>
		UsernameDisabled = 11,
		/// <summary> EMail not exist </summary>
		EMailNotExist = 12,
		/// <summary> Company is disabled </summary>
		CompanyDisabled = 13,
		/// <summary> The privacy checkbox is not checked </summary>
		PrivacyNotChecked = 14,
		/// <summary> Some empty fields exist </summary>
		EmptyFields = 15,
		/// <summary> The validation code is incorrect </summary>
		IncorrectValidationCode = 16,
		/// <summary> The date is not a real date </summary>
		IsNotADate = 17
	}

	/// <summary>
	/// The order of the static items list
	/// </summary>
	public enum OrderStaticsBy {
		/// <summary> Undefined </summary>
		Undefined = 0,
		/// <summary> Order by value desc </summary>
		ValueDESC = 1,
		/// <summary> Order by value asc </summary>
		ValueASC = 2,
		/// <summary> Order by content desc </summary>
		ContentDESC = 3,
		/// <summary> Order by content asc </summary>
		ContentASC = 4
	}

	/// <summary>
	/// Class DBClient based on DBSystem
	/// </summary>
	public class DBClient {
		protected DBBase DBBaseClass = null;
		protected DBSettings Settings = null;

		/// <summary>
		/// Default constructor
		/// </summary>
		public DBClient() {
			Settings = new DBSettings();

			Settings.Database = DBInfo.Current.Database;
			Settings.DatabaseUser = DBInfo.Current.DatabaseUser;
			Settings.IDName = DBInfo.Current.IDName;
			Settings.Password = DBInfo.Current.Password;
			Settings.Server = DBInfo.Current.Server;
			Settings.ServerConfigfile = DBInfo.Current.ServerConfigfile;
			Settings.ServerPath = DBInfo.Current.ServerPath;
			//Settings.TrustCn = DBInfo.Current.TrustCn;
			Settings.Username = DBInfo.Current.Username;
			Settings.SystemType = DBSystemType.MSSQL;

			DBBaseClass = new DBBase(Settings);
		}

		/// <summary>
		/// Update a dataset in a specific table
		/// </summary>
		/// <param name="dsData"></param>
		/// <param name="strTable"></param>
		/// <returns></returns>
		protected int UpdateValue(DataSet dsData, string strTable) {
			int nResult = 0;

			nResult = DBBaseClass.ExecuteUpdate(dsData, strTable);

			return nResult;
		}

		/// <summary>
		/// Get a user
		/// </summary>
		/// <param name="Username"></param>
		/// <returns></returns>
		protected DataSet GetUserByUsername(string Username) {
			StringBuilder str = new StringBuilder();

			str.Append("SELECT *");
			str.Append(" FROM [dbo].[tbl_user]");
			str.Append(" INNER JOIN [dbo].[tbl_usergroup]");
			str.Append(" ON [tbl_user].[group_pkid] = [tbl_usergroup].[pkid]");
			str.Append(" WHERE [tbl_user].[username] = '" + Username + "'");

			DataSet dsData = DBBaseClass.ExecuteQuery(str.ToString());

			return dsData;
		}

		/// <summary>
		/// Get a user
		/// </summary>
		/// <param name="UID"></param>
		/// <returns></returns>
		protected DataSet GetUserWithoutGroup(string UID) {
			StringBuilder str = new StringBuilder();

			str.Append("SELECT * FROM [dbo].[tbl_user]");
			str.Append(" WHERE [tbl_user].[pkid] = '" + UID + "'");

			DataSet dsData = DBBaseClass.ExecuteQuery(str.ToString());

			return dsData;
		}

		/// <summary>
		/// Get a user
		/// </summary>
		/// <param name="UID"></param>
		/// <returns></returns>
		protected DataSet GetUser(string UID) {
			StringBuilder str = new StringBuilder();

			str.Append("SELECT *");
			str.Append(" FROM [dbo].[tbl_user]");
			str.Append(" INNER JOIN [dbo].[tbl_usergroup]");
			str.Append(" ON [tbl_user].[group_pkid] = [tbl_usergroup].[pkid]");
			str.Append(" WHERE [tbl_user].[pkid] = '" + UID + "'");

			DataSet dsData = DBBaseClass.ExecuteQuery(str.ToString());

			return dsData;
		}

		/// <summary>
		/// Get statics
		/// </summary>
		/// <param name="Tag"></param>
		/// <param name="osb"></param>
		/// <returns></returns>
		protected DataSet GetStatics(string Tag, OrderStaticsBy osb) {
			StringBuilder str = new StringBuilder();

			str.Append("SELECT *");
			str.Append(" FROM [dbo].[tbl_static]");
			str.Append(" WHERE [tag] = '" + Tag + "'");

			switch(osb) {
				case OrderStaticsBy.Undefined:
					str.Append(" ORDER BY [value] ASC");
					break;

				case OrderStaticsBy.ValueASC:
					str.Append(" ORDER BY [value] ASC");
					break;

				case OrderStaticsBy.ValueDESC:
					str.Append(" ORDER BY [value] DESC");
					break;

				case OrderStaticsBy.ContentASC:
					str.Append(" ORDER BY [content] ASC");
					break;

				case OrderStaticsBy.ContentDESC:
					str.Append(" ORDER BY [content] DESC");
					break;
			}

			DataSet dsData = DBBaseClass.ExecuteQuery(str.ToString());

			return dsData;
		}

		/// <summary>
		/// Get statics
		/// </summary>
		/// <param name="Tag"></param>
		/// <param name="Value"></param>
		/// <returns></returns>
		protected DataSet GetStatic(string Tag, string Value) {
			StringBuilder str = new StringBuilder();

			str.Append("SELECT *");
			str.Append(" FROM [dbo].[tbl_static]");
			str.Append(" WHERE [tag] = '" + Tag + "'");
			str.Append(" AND [value] = '" + Value + "'");
			str.Append(" ORDER BY [value] ASC");

			DataSet dsData = DBBaseClass.ExecuteQuery(str.ToString());

			return dsData;
		}

		/// <summary>
		/// Login
		/// </summary>
		/// <param name="Username">The username</param>
		/// <param name="Password">The password</param>
		/// <param name="Session"></param>
		/// <returns></returns>
		public ErrorType Login(string Username, byte[] Password) {
			byte[] byBuffer = new byte[16];
			byte[] byBuffer2 = new byte[16];
			bool bCheck = true;
			ErrorType err = new ErrorType();
			DataTableReader oDTR = null;

			StringBuilder str = new StringBuilder();

			str.Append("SELECT usr.*");
			str.Append(" FROM [dbo].[tbl_user] AS usr");
			str.Append(" INNER JOIN [dbo].[tbl_usergroup] AS grp");
			str.Append(" ON usr.group_pkid = grp.pkid");
			str.Append(" WHERE usr.username = '" + Username + "'");
			str.Append(" AND usr.enabled = 1");

			DataSet dsData = this.DBBaseClass.ExecuteQuery(str.ToString());

			if(dsData.Tables[0].Rows.Count > 0) {
				oDTR = dsData.CreateDataReader();
				oDTR.Read();

				byBuffer2 = Password;

				oDTR.GetBytes(oDTR.GetOrdinal("password"), 0, byBuffer, 0, 16);

				for(int i = 0; i < byBuffer.Length; i++) {
					if(byBuffer[i] != byBuffer2[i]) bCheck = false;
				}

				//bCheck = true;

				if(bCheck) {
					err = ErrorType.NoError;
				}
				else {
					err = ErrorType.IncorrectPassword;
				}
			}
			else {
				err = ErrorType.DefaultLoginError;
			}

			return err;
		}
	}
}
